/**
 *
 * @file      GraphicsScene.h
 * @brief     Graphics Scene. Draw Background and Auto Scale
 * @author    maguiwa(maguiwa520@163.com)
 * @date      2024-9-24 16:32
 *
 */
#pragma once
#include "GraphicsAPI.h"
#include "Define.h"
#include <QGraphicsScene>

namespace Graphics
{
	class ScenePrivater;
	class GraphicsItem;
	class GraphicsLineItem;
    /**
     * @brief     Graphics Scene Class
     * @author    maguiwa(maguiwa520@163.com)
     * @date      2024-9-24 16:33
     */
	class GRAPHICS_API GraphicsScene : public QGraphicsScene
	{
		Q_OBJECT

		Q_PROPERTY(QPen darkPen READ darkPen WRITE setDarkPen)
		Q_PROPERTY(QPen lightPen READ lightPen WRITE setLightPen)
		Q_PROPERTY(SceneInterval sceneInterval READ sceneInterval WRITE setSceneInterval)
		Q_PROPERTY(bool showGrid READ showGrid WRITE setShowGrid)
	public:
        /**
         * @brief     scene background grid interval
         * @author    maguiwa(maguiwa520@163.com)
         * @date      2024-9-24 16:33
         */
		struct SceneInterval
		{
            /**
             * @brief     big grid interval
             * @author    maguiwa(maguiwa520@163.com)
             * @date      2024-9-24 16:34
             */
			int bigInterval{ 50 };
            /**
             * @brief     small grid interval
             * @author    maguiwa(maguiwa520@163.com)
             * @date      2024-9-24 16:34
             */
			int smallInterval{ 25 };
		};

		/**
		 * @brief     constructor
		 * @param     parent[i]. parent object
		 * @return    GraphicsScene object
		 * @author    maguiwa (maguiwa520@163.com)
		 * @date 	  2024-9-24 16:34
		 */
		explicit GraphicsScene(QObject *parent = nullptr);

		/**
		 * @brief     constructor
		 * @param     sceneRect[i]. scene rect
		 * @param     parent[i]. parent object
		 * @return    GraphicsScene object
		 * @author    maguiwa (maguiwa520@163.com)
		 * @date 	  2024-9-24 16:35
		 */
		explicit GraphicsScene(const QRectF &sceneRect, QObject *parent = nullptr);

		/**
		 * @brief     constructor
		 * @param     x[i]. scene pos x
		 * @param     y[i]. scene pos y
		 * @param     width[i]. scene width
		 * @param     height[i]. scene height
		 * @param     parent[i]. parent object
		 * @return    GraphicsScene object
		 * @author    maguiwa (maguiwa520@163.com)
		 * @date 	  2024-9-24 16:36
		 */
		explicit GraphicsScene(qreal x, qreal y, qreal width, qreal height, QObject *parent = nullptr);

		/**
		 * @brief     destructor
		 * @author    maguiwa (maguiwa520@163.com)
		 * @date 	  2024-9-24 16:37
		 */
		virtual ~GraphicsScene();

		/**
		 * @brief     get big background grid pen 
		 * @return    QPen . big background grid pen
		 * @author    maguiwa (maguiwa520@163.com)
		 * @date 	  2024-9-24 16:37
		 */
		QPen darkPen() const;

		/**
		 * @brief     set big background grid pen
		 * @param     pen[i] . big background grid pen
		 * @return    void 
		 * @author    maguiwa (maguiwa520@163.com)
		 * @date 	  2024-9-24 16:38
		 */
		void setDarkPen(QPen pen);

		/**
		 * @brief     get small background grid pen
		 * @return    QPen . small background grid pen
		 * @author    maguiwa (maguiwa520@163.com)
		 * @date 	  2024-9-24 16:38
		 */
		QPen lightPen() const;

		/**
		 * @brief     set small background grid pen
		 * @param     pen[i] . small background grid pen
		 * @return    void 
		 * @author    maguiwa (maguiwa520@163.com)
		 * @date 	  2024-9-24 16:38
		 */
		void setLightPen(QPen pen);

		/**
		 * @brief     get if show background grid
		 * @return    bool . is show background grid
		 * @author    maguiwa (maguiwa520@163.com)
		 * @date 	  2024-9-24 16:39
		 */
		bool showGrid() const;

		/**
		 * @brief     set show background grid
		 * @param     show[i] . show
		 * @return    void 
		 * @author    maguiwa (maguiwa520@163.com)
		 * @date 	  2024-9-24 16:43
		 */
		void setShowGrid(bool show);

		/**
		 * @brief     get background grid interval
		 * @return    Graphics::GraphicsScene::SceneInterval . background grid interval 
		 * @author    maguiwa (maguiwa520@163.com)
		 * @date 	  2024-9-24 16:44
		 */
		SceneInterval sceneInterval() const;

		/**
		 * @brief     set background grid interval
		 * @param     interval[i] . background grid interval
		 * @return    void 
		 * @author    maguiwa (maguiwa520@163.com)
		 * @date 	  2024-9-24 16:44
		 */
		void setSceneInterval(SceneInterval interval);

		/**
		 * @brief     while item out scene. update scene rect to contains item.
		 * @return    void 
		 * @author    maguiwa (maguiwa520@163.com)
		 * @date 	  2024-9-24 16:45
		 */
		void updateSceneRect();

		/**
		 * @brief     set canvas mode
		 * @param     mode[i] . canvas mode
		 * @return    void 
		 * @author    maguiwa (maguiwa520@163.com)
		 * @date 	  2024-9-24 16:46
		 */
		void setCanvasMode(CanvasMode mode);

		/**
		 * @brief     get canvas mode
		 * @return    CanvasMode . canvas mode
		 * @author    maguiwa (maguiwa520@163.com)
		 * @date 	  2024-9-24 16:46
		 */
		CanvasMode canvasMode() const;

		/**
		 * @brief     draw background 
		 * @param     painter[i]. painter
		 * @param     rect[i]. draw rect
		 * @return    void 
		 * @author    maguiwa (maguiwa520@163.com)
		 * @date 	  2024-9-24 16:46
		 */
		void drawBackground(QPainter *painter, const QRectF &rect) override;

		/**
		* @brief     update current item 's relation lines
		* @param     item[i]. current graphics item
		* @return    void
		* @author    maguiwa (maguiwa520@163.com)
		* @date 	  2024-9-2 18:39
		*/
		virtual void updateLineItem(GraphicsItem * item);

		/**
		 * @brief     get current selected component item list
		 * @return    QList<GraphicsItem *> . component item list
		 * @author    maguiwa (maguiwa520@163.com)
		 * @date 	  2024-9-3 13:59
		 */
		QList<GraphicsItem *> selectedComponents() const;

	private slots:
		/**
		 * @brief     in scene. selection has changed
		 * @return    void 
		 * @author    maguiwa (maguiwa520@163.com)
		 * @date 	  2024-9-3 10:10
		 */
		void onSelectionChanged();

	private:
        /**
         * @brief     Graphics Scene Private Part
         * @author    maguiwa(maguiwa520@163.com)
         * @date      2024-9-24 16:42
         */
		ScenePrivater * _privater{};
	};
}